package org.cxa.rpc.cloud.configurationConsole.userManagement;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.SwingConstants;

import org.cxa.rpc.cloud.client.CloudClient.CloudClientListenerAdapter;
import org.cxa.rpc.cloud.client.TransientDevice;
import org.cxa.rpc.cloud.server.components.authentication.Group;
import org.cxa.rpc.cloud.server.components.authentication.User;
import org.cxa.rpc.messages.ResponseRpcMessage;
import org.cxa.rpc.transportChannel.TransportChannel.DisconnectReason;

import javax.swing.JScrollPane;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.ListSelectionModel;


public class AddUserDialog extends JDialog
{
	private static final long serialVersionUID = -2516136740832390049L;
	
	private final JPanel contentPanel = new JPanel();
	
	private final JTextField txtEmailAddress;
	private final JTextField txtPassword;
	private final JTable tblGroups;
	private final JCheckBox chkEnabled;

	private final TransientDevice tDev;

	/**
	 * Create the dialog.
	 */
	public AddUserDialog(TransientDevice tDevIn)
	{
		this.tDev = tDevIn;
		this.tDev.addListener(new CloudClientListenerAdapter()
		{
			@Override
			public void onDisconnect(DisconnectReason reasonIn, boolean willAttemptReconnectIn)
			{
				JOptionPane.showMessageDialog(null, "Client disconnected", "Error adding user", JOptionPane.ERROR_MESSAGE);
				AddUserDialog.this.dispose();
			}
		});
		
		setModal(true);
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setTitle("Add new user");
		setBounds(100, 100, 450, 300);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(new FormLayout(new ColumnSpec[] {
				FormFactory.RELATED_GAP_COLSPEC,
				FormFactory.DEFAULT_COLSPEC,
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("default:grow"),},
			new RowSpec[] {
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				RowSpec.decode("default:grow"),
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,}));
		
		JLabel lblEmailAddress = new JLabel("E-mail Address:");
		contentPanel.add(lblEmailAddress, "2, 2, right, default");
		txtEmailAddress = new JTextField();
		contentPanel.add(txtEmailAddress, "4, 2, fill, default");
		txtEmailAddress.setColumns(10);

		JLabel lblPassword = new JLabel("Password:");
		contentPanel.add(lblPassword, "2, 4, right, default");
		txtPassword = new JTextField();
		txtPassword.setColumns(10);
		contentPanel.add(txtPassword, "4, 4, fill, default");
	
		JLabel lblGroups = new JLabel("Groups:");
		lblGroups.setHorizontalAlignment(SwingConstants.RIGHT);
		lblGroups.setVerticalAlignment(SwingConstants.TOP);
		contentPanel.add(lblGroups, "2, 6, default, top");
		
		JScrollPane scrollPane = new JScrollPane();
		contentPanel.add(scrollPane, "4, 6, fill, fill");
		tblGroups = new JTable();
		tblGroups.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		tblGroups.setModel(new GroupTableModel(tDevIn));
		scrollPane.setViewportView(tblGroups);
		
		JLabel lblEnabled = new JLabel("Enabled:");
		lblEnabled.setHorizontalAlignment(SwingConstants.RIGHT);
		contentPanel.add(lblEnabled, "2, 8");
		chkEnabled = new JCheckBox("");
		chkEnabled.setHorizontalAlignment(SwingConstants.LEFT);
		contentPanel.add(chkEnabled, "4, 8");
	
		JPanel buttonPane = new JPanel();
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);
		
		JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent arg0)
			{
				// don't do anything but go away
				dispose();
			}
		});
		btnCancel.setActionCommand("Cancel");
		buttonPane.add(btnCancel);

		JButton btnOk = new JButton("OK");
		btnOk.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				List<Integer> groups = new ArrayList<Integer>();
				for( int currRow : tblGroups.getSelectedRows() )
				{
					Group currGroup = ((GroupTableModel)tblGroups.getModel()).getGroupAtRow(currRow);
					if( currGroup != null ) groups.add(currGroup.getId());
				}
				
				User userToAdd = new User(txtEmailAddress.getText(), txtPassword.getText(), groups.toArray(new Integer[groups.size()]), chkEnabled.isSelected());
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("user", userToAdd);
				
				ResponseRpcMessage resp = tDev.sendRequest("/sys/auth", "addUser", params);
				if( !resp.getWasSuccessful() )
				{
					JOptionPane.showMessageDialog(null, String.format("Error adding user:\n%s", resp.getException().getFormattedErrorString())); 
				}
				else
				{
					JOptionPane.showMessageDialog(null, 
							String.format("Added user: '%s'", txtEmailAddress.getText()), 
							"Added user", JOptionPane.INFORMATION_MESSAGE);
					AddUserDialog.this.dispose();
				}
				
			}
		});
		btnOk.setActionCommand("OK");
		buttonPane.add(btnOk);
		getRootPane().setDefaultButton(btnOk);
		
		
		// now we need to grab the list of groups from the server
		if( tDevIn != null )
		{
			if( !((GroupTableModel)tblGroups.getModel()).refreshFromServer() )
			{
				JOptionPane.showMessageDialog(null, "Error retrieving group list", "Error adding user", JOptionPane.ERROR_MESSAGE);
				this.dispose();
				return;
			}
		}
	}

}
